PROP_CURSOR
};
+typedef enum {
+ CLEAR_BG_NONE,
+ CLEAR_BG_WINCLEARED, /* Clear backgrounds except those that the window system clears */
+ CLEAR_BG_ALL
+} ClearBg;
+
struct _GdkWindowPaint
{
GdkRegion *region;
static void impl_window_add_update_area (GdkWindowObject *impl_window,
GdkRegion *region);
static void gdk_window_region_move_free (GdkWindowRegionMove *move);
+static void gdk_window_invalidate_region_full (GdkWindow *window,
+ const GdkRegion *region,
+ gboolean invalidate_children,
+ ClearBg clear_bg);
+static void gdk_window_invalidate_rect_full (GdkWindow *window,
+ const GdkRectangle *rect,
+ gboolean invalidate_children,
+ ClearBg clear_bg);
static guint signals[LAST_SIGNAL] = { 0 };
gdk_region_subtract (exposure_region, clip);
gdk_region_destroy (clip);
- gdk_window_invalidate_region (GDK_WINDOW (private),
- exposure_region,
- _gdk_gc_get_subwindow (gc) == GDK_INCLUDE_INFERIORS);
+ gdk_window_invalidate_region_full (GDK_WINDOW (private),
+ exposure_region,
+ _gdk_gc_get_subwindow (gc) == GDK_INCLUDE_INFERIORS,
+ CLEAR_BG_ALL);
gdk_region_destroy (exposure_region);
}
g_object_unref (window);
}
-/**
- * gdk_window_invalidate_rect:
- * @window: a #GdkWindow
- * @rect: rectangle to invalidate or %NULL to invalidate the whole
- * window
- * @invalidate_children: whether to also invalidate child windows
- *
- * A convenience wrapper around gdk_window_invalidate_region() which
- * invalidates a rectangular region. See
- * gdk_window_invalidate_region() for details.
- **/
-void
-gdk_window_invalidate_rect (GdkWindow *window,
- const GdkRectangle *rect,
- gboolean invalidate_children)
+static void
+gdk_window_invalidate_rect_full (GdkWindow *window,
+ const GdkRectangle *rect,
+ gboolean invalidate_children,
+ ClearBg clear_bg)
{
GdkRectangle window_rect;
GdkRegion *region;
}
region = gdk_region_rectangle (rect);
- gdk_window_invalidate_region (window, region, invalidate_children);
+ gdk_window_invalidate_region_full (window, region, invalidate_children, clear_bg);
gdk_region_destroy (region);
}
+/**
+ * gdk_window_invalidate_rect:
+ * @window: a #GdkWindow
+ * @rect: rectangle to invalidate or %NULL to invalidate the whole
+ * window
+ * @invalidate_children: whether to also invalidate child windows
+ *
+ * A convenience wrapper around gdk_window_invalidate_region() which
+ * invalidates a rectangular region. See
+ * gdk_window_invalidate_region() for details.
+ **/
+void
+gdk_window_invalidate_rect (GdkWindow *window,
+ const GdkRectangle *rect,
+ gboolean invalidate_children)
+{
+ gdk_window_invalidate_rect_full (window, rect, invalidate_children, CLEAR_BG_NONE);
+}
+
static void
draw_ugly_color (GdkWindow *window,
const GdkRegion *region)
}
}
-/**
- * gdk_window_invalidate_maybe_recurse:
- * @window: a #GdkWindow
- * @region: a #GdkRegion
- * @child_func: function to use to decide if to recurse to a child,
- * %NULL means never recurse.
- * @user_data: data passed to @child_func
- *
- * Adds @region to the update area for @window. The update area is the
- * region that needs to be redrawn, or "dirty region." The call
- * gdk_window_process_updates() sends one or more expose events to the
- * window, which together cover the entire update area. An
- * application would normally redraw the contents of @window in
- * response to those expose events.
- *
- * GDK will call gdk_window_process_all_updates() on your behalf
- * whenever your program returns to the main loop and becomes idle, so
- * normally there's no need to do that manually, you just need to
- * invalidate regions that you know should be redrawn.
- *
- * The @child_func parameter controls whether the region of
- * each child window that intersects @region will also be invalidated.
- * Only children for which @child_func returns TRUE will have the area
- * invalidated.
- **/
-void
-gdk_window_invalidate_maybe_recurse (GdkWindow *window,
- const GdkRegion *region,
- gboolean (*child_func) (GdkWindow *,
- gpointer),
- gpointer user_data)
+/* clear_bg controls if the region will be cleared to
+ * the background color/pixmap if the exposure mask is not
+ * set for the window, whereas this might not otherwise be
+ * done (unless necessary to emulate background settings).
+ * Set this to CLEAR_BG_WINCLEARED or CLEAR_BG_ALL if you
+ * need to clear the background, such as when exposing the area beneath a
+ * hidden or moved window, but not when an app requests repaint or when the
+ * windowing system exposes a newly visible area (because then the windowing
+ * system has already cleared the area).
+ */
+static void
+gdk_window_invalidate_maybe_recurse_full (GdkWindow *window,
+ const GdkRegion *region,
+ ClearBg clear_bg,
+ gboolean (*child_func) (GdkWindow *,
+ gpointer),
+ gpointer user_data)
{
GdkWindowObject *private = (GdkWindowObject *)window;
GdkWindowObject *impl_window;
gdk_region_offset (child_region, - child_rect.x, - child_rect.y);
gdk_region_intersect (child_region, tmp);
- gdk_window_invalidate_maybe_recurse ((GdkWindow *)child,
- child_region, child_func, user_data);
+ gdk_window_invalidate_maybe_recurse_full ((GdkWindow *)child,
+ child_region, clear_bg, child_func, user_data);
gdk_region_destroy (tmp);
}
/* Convert to impl coords */
gdk_region_offset (visible_region, private->abs_x, private->abs_y);
- impl_window_add_update_area (impl_window, visible_region);
+
+ /* Only invalidate area if app requested expose events or if
+ we need to clear the area (by request or to emulate background
+ clearing for non-native windows or native windows with no support
+ for window backgrounds */
+ if (private->event_mask & GDK_EXPOSURE_MASK ||
+ clear_bg == CLEAR_BG_ALL ||
+ (clear_bg == CLEAR_BG_WINCLEARED &&
+ (!clears_as_native (private) ||
+ !GDK_WINDOW_IMPL_GET_IFACE (private->impl)->supports_native_bg)))
+ impl_window_add_update_area (impl_window, visible_region);
}
gdk_region_destroy (visible_region);
}
+/**
+ * gdk_window_invalidate_maybe_recurse:
+ * @window: a #GdkWindow
+ * @region: a #GdkRegion
+ * @child_func: function to use to decide if to recurse to a child,
+ * %NULL means never recurse.
+ * @user_data: data passed to @child_func
+ *
+ * Adds @region to the update area for @window. The update area is the
+ * region that needs to be redrawn, or "dirty region." The call
+ * gdk_window_process_updates() sends one or more expose events to the
+ * window, which together cover the entire update area. An
+ * application would normally redraw the contents of @window in
+ * response to those expose events.
+ *
+ * GDK will call gdk_window_process_all_updates() on your behalf
+ * whenever your program returns to the main loop and becomes idle, so
+ * normally there's no need to do that manually, you just need to
+ * invalidate regions that you know should be redrawn.
+ *
+ * The @child_func parameter controls whether the region of
+ * each child window that intersects @region will also be invalidated.
+ * Only children for which @child_func returns TRUE will have the area
+ * invalidated.
+ **/
+void
+gdk_window_invalidate_maybe_recurse (GdkWindow *window,
+ const GdkRegion *region,
+ gboolean (*child_func) (GdkWindow *,
+ gpointer),
+ gpointer user_data)
+{
+ gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_NONE,
+ child_func, user_data);
+}
+
static gboolean
true_predicate (GdkWindow *window,
gpointer user_data)
return TRUE;
}
+static void
+gdk_window_invalidate_region_full (GdkWindow *window,
+ const GdkRegion *region,
+ gboolean invalidate_children,
+ ClearBg clear_bg)
+{
+ gdk_window_invalidate_maybe_recurse_full (window, region, clear_bg,
+ invalidate_children ?
+ true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
+ NULL);
+}
+
/**
* gdk_window_invalidate_region:
* @window: a #GdkWindow
gdk_region_destroy (move_region);
}
- gdk_window_invalidate_maybe_recurse (window, region,
- (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl,
- NULL);
+ gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_WINCLEARED,
+ (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl,
+ NULL);
}
if (gdk_window_is_viewable (window))
{
_gdk_synthesize_crossing_events_for_geometry_change (window);
- gdk_window_invalidate_rect (window, NULL, TRUE);
+ gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
}
}
}
new_region = gdk_region_copy (private->clip_region);
gdk_region_subtract (new_region, old_region);
- gdk_window_invalidate_region (window, new_region, TRUE);
+ gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_ALL);
gdk_region_destroy (old_region);
gdk_region_destroy (new_region);
child.height = private->height;
gdk_rectangle_intersect (&r, &child, &r);
- gdk_window_invalidate_rect (GDK_WINDOW (private->parent), &r, TRUE);
+ gdk_window_invalidate_rect_full (GDK_WINDOW (private->parent), &r, TRUE, CLEAR_BG_ALL);
}
* roundtrip
*/
gdk_region_subtract (new_region, old_region);
- gdk_window_invalidate_region (window, new_region, TRUE);
+ gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_WINCLEARED);
gdk_region_destroy (old_region);
gdk_region_destroy (new_region);
gdk_region_intersect (old_native_child_region, new_native_child_region);
gdk_region_subtract (new_region, old_native_child_region);
}
- gdk_window_invalidate_region (GDK_WINDOW (private->parent), new_region, TRUE);
+ gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), new_region, TRUE, CLEAR_BG_ALL);
gdk_region_destroy (old_region);
gdk_region_destroy (new_region);
gdk_region_intersect (old_native_child_region, new_native_child_region);
gdk_region_subtract (noncopy_area, old_native_child_region);
}
- gdk_window_invalidate_region (window, noncopy_area, TRUE);
+ gdk_window_invalidate_region_full (window, noncopy_area, TRUE, CLEAR_BG_ALL);
gdk_region_destroy (noncopy_area);
gdk_region_offset (copy_area, private->abs_x, private->abs_y);
move_region_on_impl (impl_window, copy_area, dx, dy); /* Takes ownership of copy_area */
- gdk_window_invalidate_region (window, nocopy_area, FALSE);
+ gdk_window_invalidate_region_full (window, nocopy_area, FALSE, CLEAR_BG_ALL);
gdk_region_destroy (nocopy_area);
}
diff = gdk_region_copy (new_region);
gdk_region_subtract (diff, old_region);
- gdk_window_invalidate_region (window, diff, TRUE);
+ gdk_window_invalidate_region_full (window, diff, TRUE, CLEAR_BG_ALL);
gdk_region_destroy (diff);
/* Adjust region to parent window coords */
gdk_region_offset (diff, private->x, private->y);
- gdk_window_invalidate_region (GDK_WINDOW (private->parent), diff, TRUE);
+ gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), diff, TRUE, CLEAR_BG_ALL);
gdk_region_destroy (diff);
}